<template>
    <div style="width: 100%;height: 100%;background: white">
        <div class="filter-component">
            <div
                 v-for="(paramMapping,index) in filter.publish.paramMapping">
                <div :class="[filter.layout=='standard'?'filter-component-list':'filter-component-list-vertical']">
                    <div  :class="[filter.layout=='standard'?'filter-component-list-le':'']">{{paramMapping.label}}</div>
                    <div  :class="[filter.layout=='standard'?'filter-component-list-ri':'filter-component-list-ri-vertical']">
                        <input v-if="paramMapping.type=='text'" class="ant-input" v-model="paramMapping.value"
                                 @change="onChange(paramMapping)"
                                 allowClear/>
                        <input type="number" class="ant-input" v-else-if="paramMapping.type=='number'" v-model="paramMapping.value"
                                 @change="onChange(paramMapping)"/>
                        <next-data-select
                            :multiple="paramMapping.settings.multiSelect"
                            v-if="paramMapping.type=='select'"
                            v-model="paramMapping.value"
                            @change="onChange(paramMapping)"
                            :options="optionObj[paramMapping.key]"
                            :disabled="false"
                            :placeholder="i18n('dropSelect','下拉选择')"
                            optionsLabelKey="label"
                            optionsValueKey="value"
                        />
                        <view v-if="paramMapping.type=='tree'">
                           <div class="filter-tree">
                               <span v-if="paramMapping.values" style="margin-right: 1rem">{{paramMapping.values}}</span>
                               <button style="margin-left: 0rem" size="mini" @click="selectTree(paramMapping.key)">{{i18n('select','选择')}}</button>
                           </div>
                            <next-tree
                                :ref="'nextTree'+paramMapping.key"
                                :selectParent="true"
                                :checkStrictly="false"
                                :funcMode="!paramMapping.settings.multiSelect?'radio':'checkbox'"
                                :treeData="optionObj[paramMapping.key]"
                                valueKey="value"
                                @confirm="setValue($event,index,paramMapping)"
                            />
                        </view>
                        <view v-if="paramMapping.type=='month'">
                            <div class="rx-date-select" @click="showPlugin('month'+paramMapping.key)">
                                <span :class="[paramMapping.value ==''? '':'rx-date-color']">{{ paramMapping.value || $ti18('rxDecorator.select', "请选择")}}</span>
                                <i class="iconfont icon-close" v-if="paramMapping.value" @click.stop="dateDelete(paramMapping)"></i>
                                <i class="iconfont icon-icon-test41"></i>
                            </div>
                            <lingfeng-timepicker
                                :ref="'month'+paramMapping.key"
                                type="year-month"
                                :defaultData="getDate(paramMapping,'month')"
                                :maxDate="maxDate"
                                @change="dateChange($event,paramMapping,'YYYY-MM')"></lingfeng-timepicker>
                        </view>
                        <view v-if="paramMapping.type=='year'">
                            <div class="rx-date-select" @click="showPlugin('year'+paramMapping.key)">
                                <span :class="[paramMapping.value ==''? '':'rx-date-color']">{{ paramMapping.value || $ti18('rxDecorator.select', "请选择")}}</span>
                                <i class="iconfont icon-close" v-if="paramMapping.value" @click.stop="dateDelete(paramMapping)"></i>
                                <i class="iconfont icon-icon-test41"></i>
                            </div>
                            <lingfeng-timepicker
                                :ref="'year'+paramMapping.key"
                                type="year"
                                :defaultData="getDate(paramMapping,'year')"
                                :maxDate="maxDate"
                                @change="dateChange($event,paramMapping,'YYYY')"></lingfeng-timepicker>
                        </view>
                        <view v-if="paramMapping.type=='date'">
                            <div class="rx-date-select" @click="showPlugin('date'+paramMapping.key)">
                                <span :class="[paramMapping.value ==''? '':'rx-date-color']">{{ paramMapping.value || $ti18('rxDecorator.select', "请选择")}}</span>
                                <i class="iconfont icon-close" v-if="paramMapping.value" @click.stop="dateDelete(paramMapping)"></i>
                                <i class="iconfont icon-icon-test41"></i>
                            </div>
                            <lingfeng-timepicker
                                :ref="'date'+paramMapping.key"
                                :type="paramMapping.settings.format=='YYYY-MM-DD HH:mm:ss' ? 'datetime-all' :'date' "
                                :defaultData="getDate(paramMapping,'date')"
                                :maxDate="maxDate"
                                @change="dateChange($event,paramMapping,'YYYY-MM-DD')"></lingfeng-timepicker>
                        </view>
                        <view v-if="paramMapping.type=='dateRange'">
                            <div class="rx-date-select" @click="showPlugin('date'+paramMapping.key)">
                                <span :class="[paramMapping.value ==''? '':'rx-date-color']">{{ getRangeDateStr(paramMapping.value)}}</span>
                                <i class="iconfont icon-close" v-if="paramMapping.value" @click.stop="dateRangeDelete(paramMapping)"></i>
                                <i class="iconfont icon-icon-test41"></i>
                            </div>
                            <lingfeng-timepicker
                                :ref="'date'+paramMapping.key"
                                :type="paramMapping.settings.format=='YYYY-MM-DD HH:mm:ss' ? 'datetime-all-range' :'date-range' "
                                :defaultData="getRangeDate(paramMapping)"
                                :maxDate="maxDate"
                                @change="rangeDateChange($event,paramMapping)"></lingfeng-timepicker>
                        </view>
                        <view v-if="paramMapping.type=='user'">
                            <RxVueUserDialog v-model="paramMapping.values" @change="onChange(paramMapping)" :single="!paramMapping.settings.multiSelect"></RxVueUserDialog>
                        </view>
                        <view v-if="paramMapping.type=='group'">
                            <RxVueGroupDialog v-model="paramMapping.values" @change="onChange(paramMapping)" :single="!paramMapping.settings.multiSelect"></RxVueGroupDialog>
                        </view>
                        <view v-if="paramMapping.type=='dialog'">
                            <rx-edit-button v-model="paramMapping.value" :ref="'dialog'+paramMapping.key" @btnClick="openDialog($event,paramMapping)" @deleteClose="deleteClose($event,paramMapping)"></rx-edit-button>
                        </view>
                    </div>
                </div>
            </div>
            <div class="filter-button" v-if="filter.showButton">
                <button type="primary" style="flex: 1;"  @click="search()">{{i18n('searchBtn','查询')}}</button>
                <button style="flex: 1;border:1px solid #d9d9d9" @click="reset">{{i18n('resetBtn','重置')}}</button>
            </div>
        </div>
    </div>
</template>

<script>
/**
 * 自定义页面(筛选器组件)
 */
import {debounce} from "lodash-es";
import {FormApi} from "@/api/FormApi.js";
import dayjs from 'dayjs'
import Util from "@/js/Util.js"
import BusEvent from "../BusEvent.js";
import RxVueUserDialog from '@/components/RxVueUserDialog';
import RxVueGroupDialog from '@/components/RxVueGroupDialog.vue';
import RxEditButton from "@/components/RxEditButton";
import Dialog from "@/js/Dialog.js";
import Button from "../../../../../../uni_modules/uv-ui-tools/libs/mixin/button";

export default {
    name: "FilterView",
    mixins:[BusEvent],
    components: {
        Button,
        RxVueUserDialog,
        RxVueGroupDialog,
        RxEditButton,
    },
    props: {
        config:{
            type:Object,
            default:()=>{
                return {}
            }
        }
    },
    computed: {
        maxDate() {
            return {year:dayjs().year() + 10};
        }
    },
    data() {
        return {
            //筛选器
            filter: {},
            //下拉框数据
            optionObj:{}
        }
    },
    created() {
        this.initConfig();
    },
    mounted(){
        let self = this;
        this.$nextTick(function (){
                self.initParamMapping(false)//执行方法
        })
    },
    methods: {
        i18n(name,text,key){
            return this.$ti18(name,text,"formCustomViewLang",key);
        },
        selectTree(key){
            this.$refs['nextTree'+key][0].showTree=true;
        },
        setValue(data,index,paramMapping){
            if(data){
                let values=[];
                let labels=[];
                for (let i = 0; i < data.length; i++) {
                    values.push(data[i].value);
                    labels.push(data[i].label);
                }
                this.filter.publish.paramMapping[index].values = labels.join(",")
                this.filter.publish.paramMapping[index].value = values.join(",")
            }
            this.onChange(paramMapping);
        },
        initConfig() {
            this.filter = JSON.parse(JSON.stringify(this.config));
            this.initOptions();
        },
        //构建参数并触发事件
        initParamMapping(reset) {
            let paramMappings = this.filter.publish.paramMapping;
            let params = {};
            for (let i = 0; i < paramMappings.length; i++) {
                let paramMapping = paramMappings[i];
                if (reset) {
                    paramMapping.value = "";
                    paramMapping.values=""
                }
                if((paramMapping.type=='user' || paramMapping.type=='group') && paramMapping.values){
                    let ary=[];
                    for (let i = 0; i < paramMapping.values.length; i++) {
                        ary.push(paramMapping.values[i].id);
                    }
                    paramMapping.value=ary.join(",");
                }if(paramMapping.type=='date'){
                    params[paramMapping.key] =paramMapping.value?dayjs(paramMapping.value).format(paramMapping.settings.format || 'YYYY-MM-DD'):''
                }else if(paramMapping.type=='dateRange' && paramMapping.value){
                    let item = []
                    paramMapping.value.map(vl=>{
                        item.push(vl?dayjs(vl).format(paramMapping.settings.format || 'YYYY-MM-DD'):'')
                    })
                    params[paramMapping.key] = item
                }else{
                    params[paramMapping.key] = paramMapping.value || "";
                }
            }
            //触发事件
            this.handEvent(params);
        },
        onChange: debounce(function (paramMapping) {
            //查找下拉框是否配置当前为参数
            this.findSelectParams(paramMapping);
            //未配置按钮则直接触发事件
            if (!this.filter.showButton) {
                this.initParamMapping(false);
            }
        }, 500),
        //触发事件
        handEvent(params) {
            this.$eventBus.$emit("formCustomViewEvent", {component: this.config.alias, params: params});
        },
        search() {
            this.initParamMapping(false);
        },
        reset() {
            this.initParamMapping(true);
        },
        async initOptions(){
            //下拉框获取选项数据
            for (let i = 0; i < this.filter.publish.paramMapping.length; i++) {
                let paramMapping = this.filter.publish.paramMapping[i];
                if (paramMapping.settings && (paramMapping.type == "select" || paramMapping.type == "tree")) {
                    if(paramMapping.values){
                        paramMapping.value = paramMapping.values
                    }
                    await this.getOptions(paramMapping.settings,paramMapping.key,"",paramMapping.type,paramMapping);
                    if(paramMapping.settings.multiSelect){
                        paramMapping.value = [];
                    }
                }
            }
        },
        async getOptions(settings,key,params,type,paramMapping){
            if(!settings){
                return;
            }
            let options = [];
            //自定义
            if(settings.from=="self"){
                let dataSource = settings.dataSource;
                for (let j = 0; j < dataSource.length; j++) {
                    options.push({
                        value:dataSource[j].key,
                        label:dataSource[j].name,
                    })
                }
                if(paramMapping.values){
                    options.forEach((item)=>{
                        if(item.value==paramMapping.values){
                            paramMapping.values = item.label
                        }
                    })
                }
                this.optionObj[key]=options;
            }
            //数据字典
            else if(settings.from=="dic"){
                await FormApi.loadDicByPidAndDicId(settings.dicKey,"").then(res=>{
                    if(res.length && res.length>0){
                        for (let j = 0; j < res.length; j++) {
                            options.push({
                                id:res[j].pkId,
                                value:res[j].value,
                                label:res[j].name,
                                parentId:res[j].parentId,
                            })
                        }
                    }
                    if(type=='tree'){
                        if(paramMapping.values){
                            options.forEach((item)=>{
                                if(item.value==paramMapping.values){
                                    paramMapping.values = item.label
                                }
                            })
                        }
                        options=Util.listToTree(options, "id", "parentId");
                    }
                    this.optionObj[key]=options;
                });
            }
            //sql
            else if(settings.from=="sql"){
                if(!settings.sql){
                    return;
                }
                let textfield=settings.sql_textfield;
                let valuefield=settings.sql_valuefield;
                let parentfield=settings.sql_parentfield;
                let sql=JSON.parse(settings.sql).value;
                await FormApi.queryForJson(sql, {params: params}).then(res=>{
                    let data=res.data;
                    if(data.length && data.length>0) {
                        for (let j = 0; j < data.length; j++) {
                            options.push({
                                value:data[j][valuefield],
                                label:data[j][textfield],
                                parentId:data[j][parentfield],
                            })
                        }
                    }
                    if(type=='tree'){
                        if(paramMapping.values){
                            options.forEach((item)=>{
                                if(item.value==paramMapping.values){
                                    paramMapping.values = item.label
                                }
                            })
                        }
                        options=Util.listToTree(options, "value", "parentId");
                    }
                    this.optionObj[key]=options;
                });
            }
            //权限数据
            else if(settings.from=="grant"){
                if(settings.grant){
                    let grant=JSON.parse(settings.grant).value;
                    await FormApi.loadByGrant(grant).then(res => {
                        for (let j = 0; j < res.data.length; j++) {
                            options.push({
                                value:res.data[j]["value"],
                                label:res.data[j]["label"],
                                parentId:res.data[j]["parentId"]
                            })
                        }
                        if(type=='tree'){
                            options=Util.listToTree(options, "value", "parentId");
                        }
                        this.optionObj[key]=options;
                    })
                }
            }
        },
        //查找下拉框是否配置当前为参数
        findSelectParams(paramMapping){
            for (let i = 0; i <this.filter.publish.paramMapping.length; i++) {
                let mapping=this.filter.publish.paramMapping[i];
                //下拉框 自定义查询
                if((mapping.type=="select" || mapping.type=="tree") && mapping.settings.from=='sql'){
                    for (let j = 0; j < mapping.settings.paramsData.length; j++) {
                        let paramsData=mapping.settings.paramsData[j];
                        if(paramMapping.key==paramsData.bindVal){
                            let params={};
                            params[paramsData.fieldName]=paramMapping.value;
                            this.getOptions(mapping.settings,mapping.key,JSON.stringify(params),mapping.type);
                        }
                    }
                }
            }
        },
        showPlugin(key) {
            if(!this.$refs[key] || !this.$refs[key][0]){
                return;
            }
            this.$refs[key][0].show();
        },
        getDate(paramMapping,type){
            let name = {date:'startTime',month:'month',year:'year'}
            let defaultData = {};
            defaultData[name[type]] = paramMapping.value
            return defaultData;
        },
        isNumber(val) {
            return typeof val === 'number';
        },
        dateChange(value,paramMapping,format){
            if (value instanceof Object && value.hasOwnProperty("show")) {
                return;
            }
            if(this.isNumber(value)){
                value = JSON.stringify(value)
            }
            paramMapping.value=dayjs(value).format(paramMapping.settings.format || format);
            this.onChange(paramMapping);
        },
        rangeDateChange(values,paramMapping){
            if (values instanceof Object && values.hasOwnProperty("show")) {
                return;
            }
            let ary=[];
            ary.push(dayjs(values[0]).format(paramMapping.settings.format || 'YYYY-MM-DD'));
            ary.push(dayjs(values[1]).format(paramMapping.settings.format || 'YYYY-MM-DD'));
            paramMapping.value=ary;
            this.onChange(paramMapping);
        },
        dateRangeDelete(paramMapping){
            paramMapping.value = ''
        },
        dateDelete(paramMapping){
            paramMapping.value = ''
        },
        getRangeDate(paramMapping){
            let defaultData = {
                startTime: "",
                endTime: ""
            }
            if(!paramMapping.value){
                return defaultData;
            }
            defaultData.startTime =paramMapping.value[0]
            defaultData.endTime =paramMapping.value[1]
            return  defaultData;
        },
        getRangeDateStr(dates){
            let value = this.$ti18('rxDecorator.select', "请选择")
            if (dates && dates.length>1) {
                value =dates[0] + " - " + dates[1];
            }
            return value;
        },
        openDialog(vm,paramMapping){
            let settings=paramMapping.settings;
            let dialog=settings.dialog;
            let valueField=settings.valueField;
            let textField=settings.textField;
            let single=!settings.multiSelect;
            if(!dialog){
                this.$message.error(vm.$ti18('rxMsa.masWarn.configDialog',"请配置对话框"));
                return;
            }
            let self=this;
            let dialogKey=JSON.parse(dialog).value;
            let conf = {
                data: {
                    alias:dialogKey,
                    single:single
                },
                curVm: self,
            };
            Dialog.openDialog(conf,function(data){
                if(data.action !='ok'){
                    return;
                }
                let rows=data.data.rows;
                if(rows.length==0){
                    return;
                }
                let values=[];
                let texts=[];
                //多选
                if(!single) {
                    for (let i = 0; i <  rows.length; i++) {
                        values.push( rows[i][valueField]);
                        texts.push( rows[i][textField]);
                    }
                }else{
                    values.push(rows[0][valueField]);
                    texts.push(rows[0][textField]);
                }
                paramMapping.value=values.join(',');
                self.onChange(paramMapping)
            });
        },
        deleteClose(item,paramMapping){
            if(paramMapping.value){
                let value = paramMapping.value.split(",");
                value.filter((res,index)=>{
                    if(item.value ==res){
                        value.splice(index,1)
                    }
                })
                paramMapping.value=value;
                this.onChange(paramMapping)
            }
        },
    },
    watch: {
        config: {
            handler: function (val, oldVal) {
                if (val) {
                    this.initConfig();
                }
            },
            deep: true
        }
    }
}
</script>

<style scoped>
.filter-button{
    margin:2rem 0.5rem 0.5rem 0.5rem;
    display: flex;
    gap: 0.5rem;
    align-items: flex-end;
}
.filter-button button{
    height: 2rem;
    line-height: 2rem;
    font-size: 0.9rem;
}
.filter-component >>>.ant-select-tree{
    max-height: 400px!important;
    overflow: auto;
    margin-top: 10px;
}
.filter-component-list-vertical{
    margin-left: 20px;
    margin-top: 15px;
}
.filter-component-list-ri-vertical{
    margin-top: 8px;
    margin-right: 10px;
}
.filter-component-list{
    display: flex;
    align-items: center;
    line-height: 30px;
    margin-right: 10px;
    margin-top: 15px;
}
.filter-component-list-le{
    width:20%;
    text-align: right;
    margin-right: 10px
}
.filter-component-list-ri{
    flex: 1;
    margin-right: 10px;
}
.filter-component{
    display: flex;
    flex-direction: column;
}
.filter-1{
    flex: 0 0 25% !important;
}
.filter-2{
    flex: 0 0 33.33% !important;
}
.filter-3{
    flex: 0 0 66.66% !important;
}
.filter-4{
    flex: 0 0 50% !important;
}
.filter-5{
    flex: 0 0 100% !important;
}
.rx-date-color {
    color: #555555 !important;
}
.rx-date-select i {
    line-height: 1.4rem;
    height: 1.4rem;
}

.redate-canEdit {
    line-height: 1.4rem;
    color: #555555;
    font-size: 0.9rem;
}

.rx-date-select {
    display: flex;
    border: none !important;
    align-items: center;
    color: #b0b9ca !important;
}

.rx-date-select span {
    margin-right: 0.2rem;
    line-height: 1.7rem;
    flex: 1;
}
.filter-tree{
    display: flex;
    align-items: center;
}
</style>
